export class EventManager {

  private static instance: EventManager = null as unknown as EventManager;

  // 事件名字 =》 【监听者1(caller, func)，监听者2...】
  private mapEvents: any = {}; // 和Game的Node节点相关, 退出游戏，是需要清理的
  private gameMapEvents: any = {}; // 不需要清理
  public static Instance() {
    if (EventManager.instance) {
      return EventManager.instance;
    }
    EventManager.instance = new EventManager();
    return EventManager.instance;
  }
  constructor() { }

  // func(event_name: string, udata: any)
  public AddEventListener(eventName: string, caller: any, func: Function) {
    if (!this.mapEvents[eventName]) {
      this.mapEvents[eventName] = [];
    }

    var eventQueue = this.mapEvents[eventName];
    eventQueue.push({ caller: caller, func: func });
  }

  public RemoveListenner(eventName: string, caller: any, func: Function) {
    if (!this.mapEvents[eventName]) {
      return;
    }

    var eventQueue = this.mapEvents[eventName];
    for(var i = 0; i < eventQueue.length; i ++) {
      var obj = eventQueue[i];
      if (obj.caller == caller && obj.func == func) {
        eventQueue.splice(i, 1);
        break;
      }
    }

    if (eventQueue.length <= 0) {
      this.mapEvents[eventName] = null;
    }
  }
  
  public Emit(eventName: string, udata: any) {
    if (!this.mapEvents[eventName]) {
      return;
    }

    var eventQueue = this.mapEvents[eventName];
    for(var i = 0; i < eventQueue.length; i ++) {
      var obj = eventQueue[i];
      obj.func.call(obj.caller, eventName, udata);
    }
  }

  // func(event_name: string, udata: any)
  public AddGameEventListener(eventName: string, caller: any, func: Function) {
    if (!this.gameMapEvents[eventName]) {
      this.gameMapEvents[eventName] = [];
    }

    var eventQueue = this.gameMapEvents[eventName];
    eventQueue.push({ caller: caller, func: func });
  }
  
  public EmitGame(eventName: string, udata: any) {
    if (!this.gameMapEvents[eventName]) {
      return;
    }

    var eventQueue = this.gameMapEvents[eventName];
    for(var i = 0; i < eventQueue.length; i ++) {
      var obj = eventQueue[i];
      obj.func.call(obj.caller, eventName, udata);
    }
  }
  public Clear() {
    this.mapEvents = {};
  }
}

